package com.zn.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.zn.service.OptionTradeService;
import com.zn.util.Constant;
import com.zn.util.DateUtils;
import com.zn.vo.Message;
import com.zn.vo.ResultData;
import com.zn.web.dto.FuturesTradeDto;
import com.zn.web.dto.OptionTradeDto;
import com.zn.web.vo.DealRecordVo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author yinjiawei
 * 处理交易类控制层
 */
@Controller
@RequestMapping("/optionTrade")
public class OptionTradeController {
    private static final Logger LOGGER = LoggerFactory.getLogger(OptionTradeController.class);
    @Autowired
    private OptionTradeService optionTradeService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    /**
     * 买入接口 获取合约以及交易品基础数据
     * @param optionTradeDto
     * @return
     */
    @RequestMapping(value = "/buyAndSell",method = RequestMethod.POST)
    public ResponseEntity<Message> buyAbndSell(@RequestBody OptionTradeDto optionTradeDto) {
        try {
            //校验参数
            if(StringUtils.isBlank(optionTradeDto.getContractMonthName()) || optionTradeDto.getTargetCode()==null){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            ResponseEntity<Message> responseEntity=optionTradeService.checkBuyAndSell(optionTradeDto);
            return responseEntity;
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("buyAndSell....",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 请求报单接口
     * @param optionTradeDto
     * @return
     */
    @RequestMapping(value = "/reportOrder",method = RequestMethod.POST)
    public ResponseEntity<Message> reportOrder(@RequestBody OptionTradeDto optionTradeDto) {
        //校验参数
        if(StringUtils.isBlank(optionTradeDto.getCustomerId()) || StringUtils.isBlank(optionTradeDto.getContraceCode()) ||
                optionTradeDto.getVolume()==null || optionTradeDto.getLimitPrice()==null || optionTradeDto.getVolume()<=0 ||
                optionTradeDto.getIdempotency()==null){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        ResponseEntity<Message> responseEntity=null;
        try {
            /**开仓方向**/
            if(Integer.valueOf(optionTradeDto.getOffsetFlag())==0){
                Object redisIdempotency=redisTemplate.opsForValue().get(Constant.IDEMPOTENCY_REQSOPENREPORTORDER+optionTradeDto.getCustomerId()+":"+optionTradeDto.getContraceCode());
                if(redisIdempotency!=null && optionTradeDto.getIdempotency().equals(redisIdempotency.toString())){
                    LOGGER.info("接口:reportOrder 开仓，时间：" + DateUtils.parseToDateTimeStr(new Date()) + ",拦截了用户的重复提交请求,参数为：" + optionTradeDto.toString());
                    return ResponseEntity.ok(Message.REQ_SUCCESS);
                }
                responseEntity=optionTradeService.reqsOpenReportOrder(optionTradeDto);
            }
            /**平仓方向**/
            else{
                Object redisIdempotency=redisTemplate.opsForValue().get(Constant.IDEMPOTENCY_REQSCLOSEREPORTORDER+optionTradeDto.getCustomerId()+":"+optionTradeDto.getContraceCode());
                if(redisIdempotency!=null && optionTradeDto.getIdempotency().equals(redisIdempotency.toString())){
                    LOGGER.info("接口:reportOrder 平仓，时间：" + DateUtils.parseToDateTimeStr(new Date()) + ",拦截了用户的重复提交请求,参数为：" + optionTradeDto.toString());
                    return ResponseEntity.ok(Message.REQ_SUCCESS);
                }
                responseEntity=optionTradeService.reqsCloseReportOrder(optionTradeDto);
            }
            return responseEntity;
        }catch (Exception e){
            LOGGER.error("reportOrder....",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 请求撤单接口
     * @param optionTradeDto
     * @return
     */
    @RequestMapping(value = "/cancelOrder",method = RequestMethod.POST)
    public ResponseEntity<Message> cancelOrder(@RequestBody OptionTradeDto optionTradeDto) {
        //校验参数
        if(StringUtils.isBlank(optionTradeDto.getCustomerId()) || StringUtils.isBlank(optionTradeDto.getContraceCode()) ||
                StringUtils.isBlank(optionTradeDto.getOpenOrderRef()) || optionTradeDto.getIdempotency()==null){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        ResponseEntity<Message> responseEntity=null;
        try {
            responseEntity=optionTradeService.reqsCancelReportOrder(optionTradeDto);
            return responseEntity;
        }catch (Exception e){
            LOGGER.error("reportOrder....",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 获取订单数据列表
     * @param optionTradeDto
     * @return
     */
    @RequestMapping(value = "/getOrderList",method = RequestMethod.POST)
    public ResponseEntity<Message> getOrderList(@RequestBody OptionTradeDto optionTradeDto) {
        //校验参数
        if(StringUtils.isBlank(optionTradeDto.getCustomerId()) || optionTradeDto.getReqsOrderType()==null){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        try {
            List<?> list=optionTradeService.getOrderList(optionTradeDto);
            return ResponseEntity.ok(Message.page(list));
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("getOrderList....",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 校验是否在风控时间内
     * @return
     */
    private boolean checkInRiskManagement(String MonthName,Integer forceCloseAdvanceDay){
        try {
            Object deliveryDay=redisTemplate.opsForHash().get(Constant.SINA_DATA_DELIVERY_DAY,MonthName);
            ResultData resultData= JSONObject.parseObject(deliveryDay.toString(), ResultData.class);
            /**交割到期天数==强平提前天数 当天14：50无法开仓**/
            if(Integer.valueOf(resultData.getRemainderDays())==forceCloseAdvanceDay){
                Date riskManagementDate=DateUtils.convertStringToDate("HH:mm","14:50");
                Date nowDate= DateUtils.convertStringToDate("HH:mm", DateUtils.parseToDateTimeStr(new Date()));
                /**当前时间大于风控的时间 则进入风控不可开仓**/
                if(nowDate.after(riskManagementDate)){
                    return false;
                }
            }
            /**到期天数<强平提前天数 0<1 则无法开仓**/
            if(Integer.valueOf(resultData.getRemainderDays())<forceCloseAdvanceDay){
                return false;
            }
        }catch (Exception e){
            LOGGER.error("checkInRiskManagement......."+e);
        }
        return true;
    }

    /**
     *@描述 判断当前时间是否可以开平仓
     *@参数  [tradingTime, forceCloseTime]
     *@返回值  int
     *@创建人  YinJiaWei
     *@创建时间  16:28
     */
    private boolean checkContraceInCloseTime(String tradingTime,String forceCloseTime){
        boolean flag=false;
        String [] tradingTimes=tradingTime.split("\\|");
        String [] forceCloseTimes=forceCloseTime.split("\\|");
        for(String time:tradingTimes){
            String [] timeSlot = time.split("-");
            try {
                Date beginTime=null,endTime=null;
                String nowDateStr=DateUtils.convertDateToString(new Date());
                beginTime= DateUtils.convertStringToDate("yyyy-MM-dd HH:mm", nowDateStr + " " + timeSlot[0]);
                endTime=DateUtils.convertStringToDate("yyyy-MM-dd HH:mm",nowDateStr+" "+timeSlot[1]);
                Integer endTimeHour=Integer.valueOf(DateUtils.getDateTime("HH", endTime));
                Date nowDate=DateUtils.convertStringToDate("yyyy-MM-dd HH:mm", DateUtils.parseToDateTimeStr(new Date()));
                Integer advanceMin=0;
                if(endTimeHour<23){
                    beginTime=DateUtils.addDay(endTime, 1);
                }
                if(endTimeHour==11){
                    /**早盘提前分钟数**/
                    advanceMin=Integer.valueOf(forceCloseTimes[0]);
                    if(advanceMin>0){
                        beginTime=DateUtils.addMinute(endTime,-advanceMin);
                    }
                }
                if(endTimeHour==15){
                    /**午盘提前分钟数**/
                    advanceMin=Integer.valueOf(forceCloseTimes[1]);
                    if(advanceMin>0){
                        beginTime=DateUtils.addMinute(endTime, -advanceMin);
                    }
                }
                if(endTimeHour==1|| endTimeHour==23 || endTimeHour==2 ){
                    /**晚盘提前分钟数**/
                    advanceMin=Integer.valueOf(forceCloseTimes[2]);
                    if(advanceMin>0){
                        beginTime=DateUtils.addMinute(endTime, -advanceMin);
                    }
                }
                if(advanceMin>0){
                    flag=DateUtils.belongCalendar(nowDate,DateUtils.addMinute(beginTime,-1),endTime);
                    if(flag){
                        break;
                    }
                }
            } catch (ParseException e) {
                LOGGER.error("checkContraceInCloseTime....",e);
            }
        }
        return flag;
    }

}
